package com.haiermzj.client;

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import java.util.Vector;


/**
* @ClassName: SocketConnect 
* @Description: Socket TCP连接、发送、接收（回调）、断开连接 
**/
public class SocketConnect implements Runnable, Parcelable {

	private static final String TAG = "SocketConnect";
	
	/**
	 * 连接服务器失败 默认等待时间
	 */
	private static final int DISCONNECT_WAIT_TIME = 6*1000;
	
	private boolean isConnect = false;//是否连接了服务器
	private boolean isWrite = false;//是否发送数据
	private static final Vector<byte[]> datas = new Vector<byte[]>();//待发送数据队列
	private SocketBase socketBase;//socket连接
	private WriteRunnable writeRunnable;//发送数据线程
	
	private String ip = null;
	private int port = -1;
	
	
	/**
	 * 
	* <p>Title: 创建连接</p> 
	* <p>Description: </p>
	 * @param callback 回调接口
	 * @param socketConnectTestActivity
	 */
	public SocketConnect(SocketCallback callback, Context context){
		socketBase = new SocketBase(callback,context);//创建socket连接
		writeRunnable = new WriteRunnable();//创建发送线程
	}

	protected SocketConnect(Parcel in) {
		isConnect = in.readByte() != 0;
		isWrite = in.readByte() != 0;
		ip = in.readString();
		port = in.readInt();
	}

	public static final Creator<SocketConnect> CREATOR = new Creator<SocketConnect>() {
		@Override
		public SocketConnect createFromParcel(Parcel in) {
			return new SocketConnect(in);
		}

		@Override
		public SocketConnect[] newArray(int size) {
			return new SocketConnect[size];
		}
	};

	/**
	* @Description: 设置IP和端口 
	 */
	public void setRemoteAddress(String ip, int port){
		this.ip = ip;
		this.port = port;
	}
	
	
	
	@Override
	public void run() {
		if ( ip == null || port == -1 ){
			throw new NullPointerException("not set address");
		}
		
		isConnect = true;
		while ( isConnect ) {
			synchronized ( this ) {
				try {
					socketBase.connect(ip, port);//连接服务器
				} catch (Exception e) {
					Log.e(TAG, "socket发起连接异常,等待几秒重连", e);
					
					try {
						socketBase.disConnect();//断开连接
						this.wait(DISCONNECT_WAIT_TIME);
						continue;
					} catch (Exception e2) {
						e2.printStackTrace();
						continue;
					}
				}
			}
			
			isWrite = true;//设置可发送数据
			new Thread(writeRunnable).start();//启动发送线程
			try {
				socketBase.read();//获取数据
			} catch (Exception e) {
				e.printStackTrace();
			} 
//			finally{
//				writeRunnable.stop();
//				socketBase.disConnect();
//			}
		}
	}

	
	
	
	
	/**
	* @Description: 关闭服务器连接 
	 */
	public synchronized void disconnect(){
		isConnect = false;
		this.notify();
		writeRunnable.stop();//停止发送数据
		socketBase.disConnect();
	}
	

	
	/**
	* @Description: 向发送线程写入发送数据 ，发送线程发送出去
	* @param  buffer
	* @return void
	 */
	public boolean send(byte[] buffer){
		if (writeRunnable != null){
			writeRunnable.threadWrite(buffer);
			return true;
		}else{
        	return false;
		}
	}
	
	
	/**
	 * 
	* @Description: 发送数据 
	* @param  buffer
	* @return boolean
	 */
	private boolean socketWrite(byte[] buffer){
		try {
			return socketBase.write(buffer);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel parcel, int i) {
		parcel.writeByte((byte) (isConnect ? 1 : 0));
		parcel.writeByte((byte) (isWrite ? 1 : 0));
		parcel.writeString(ip);
		parcel.writeInt(port);
	}


	/**
	* @ClassName: WriteRunnable 
	* @Description: 发送数据线程类 
	* @author W18992 
	* @date 2015年12月15日 下午7:37:17 
	 */
	private class WriteRunnable implements Runnable{

		@Override
		public void run() {
			Log.i(TAG, "---TCP 发送线程开启 ---");
			while ( isWrite ){
				synchronized (this) {
					if (datas.size() <= 0){
						try {
							this.wait();//等待发送数据
						} catch (InterruptedException e) {
							continue;
						}
					}
					while (datas.size() > 0) {
						byte[] buffer = datas.remove(0);//获取一条发送数据
						if ( isWrite ){
							socketWrite(buffer);//发送数据
						}else{
							this.notify();
						}
					}
				}
			}
			Log.i(TAG, "---TCP 发送线程结束 ---");
		}
		
		/**
         * 添加数据到发送队列
         * @param buffer 数据字节
         */
		public synchronized void threadWrite(byte[] buffer){
			datas.add(buffer);//将发送数据添加到发送队列
			this.notify();//取消等待
		}
		
		public synchronized void stop(){
			isWrite = false;
			this.notify();
		}
	}
}

 
